home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume14 / pcomm / part04 < prev    next >
Encoding:
Internet Message Format  |  1988-05-17  |  52.0 KB

  1. Subject:  v14i102:  Dial out and terminal emulator, Part04/06
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: fthood!egray
  7. Posting-number: Volume 14, Issue 102
  8. Archive-name: pcomm/part04
  9.  
  10.  
  11. #! /bin/sh
  12. # This is a shell archive, meaning:
  13. # 1. Remove everything above the #! /bin/sh line.
  14. # 2. Save the resulting text in a file.
  15. # 3. Execute the file with /bin/sh (not csh) to create:
  16. #    input.c
  17. #    line_set.c
  18. #    list_dir.c
  19. #    ls_menu.c
  20. #    m_lib.c
  21. #    main.c
  22. #    n_shell.c
  23. #    p_lib.c
  24. #    pexit.c
  25. #    port.c
  26. #    redial.c
  27. export PATH; PATH=/bin:/usr/bin:$PATH
  28. echo shar: "extracting 'input.c'" '(6599 characters)'
  29. if test -f 'input.c'
  30. then
  31.     echo shar: "will not over-write existing file 'input.c'"
  32. else
  33. sed 's/^X//' << \SHAR_EOF > 'input.c'
  34. X/*
  35. X * The input routines.  These routines are run as a child process to the
  36. X * main pcomm program.
  37. X */
  38. X
  39. X#define LPR "/usr/bin/lpr"
  40. X
  41. X#define MAX_ROW    64
  42. X#define MAX_COL    128
  43. X
  44. X#include <stdio.h>
  45. X#include <signal.h>
  46. X#include <setjmp.h>
  47. X
  48. Xjmp_buf i_jmp;
  49. Xunsigned char vs[MAX_ROW][MAX_COL+2];
  50. Xint row, col;
  51. X
  52. X/*
  53. X * Read the serial port and write the characters to the screen.  Watch
  54. X * for signals from the parent process to toggle the fancy options.
  55. X * Writes the characters received to a virtual screen buffer.
  56. X */
  57. Xint
  58. Xinput(fd, add_lf, log, print, max_row, max_col, vs_file, log_file)
  59. Xint fd, add_lf, log, print, max_row, max_col;
  60. Xchar *vs_file, *log_file;
  61. X{
  62. X    FILE *logfp, *lprfp, *popen();
  63. X    int hold, skip_row, got_sig();
  64. X    unsigned char c;
  65. X    char lf=10;
  66. X    void _exit();
  67. X                    /* set the trap for the signals */
  68. X    signal(SIGALRM, SIG_IGN);
  69. X    signal(SIGUSR1, got_sig);
  70. X    signal(SIGUSR2, got_sig);
  71. X    signal(SIGINT,  got_sig);
  72. X    signal(SIGTERM, got_sig);
  73. X                    /* resonable limits */
  74. X    if (max_row > MAX_ROW)
  75. X        max_row = MAX_ROW;
  76. X    if (max_col > MAX_COL)
  77. X        max_col = MAX_COL;
  78. X                    /* read previous screen */
  79. X    if (!access(vs_file, 0)) {
  80. X        read_vs(vs_file, max_row, max_col);
  81. X        skip_row = 0;
  82. X    }
  83. X    else 
  84. X        skip_row = 1;
  85. X
  86. X    hold = 0;
  87. X                    /* startup file pointers */
  88. X    if (print)
  89. X        lprfp = popen(LPR, "w");
  90. X
  91. X    if (log && strcmp(log_file, "NOT_DEFINED"))
  92. X        logfp = fopen(log_file, "a");
  93. X
  94. X    switch(setjmp(i_jmp)) {
  95. X        case 0:            /* no signal */
  96. X            break;
  97. X        case 1:            /* toggle the data logging */
  98. X            signal(SIGUSR1, got_sig);
  99. X            if (!strcmp(log_file, "NOT_DEFINED")) {
  100. X                log = 0;
  101. X                break;
  102. X            }
  103. X            log = log ? 0 : 1;
  104. X            if (log)
  105. X                logfp = fopen(log_file, "a");
  106. X            else
  107. X                fclose(logfp);
  108. X            break;
  109. X        case 2:            /* toggle the printer */
  110. X            signal(SIGUSR2, got_sig);
  111. X            print = print ? 0 : 1;
  112. X            if (print)
  113. X                lprfp = popen(LPR, "w");
  114. X            else {
  115. X                putc(014, lprfp);
  116. X                pclose(lprfp);
  117. X            }
  118. X            break;
  119. X        case 3:            /* suspend the input */
  120. X            signal(SIGINT, got_sig);
  121. X            hold = hold ? 0 : 1;
  122. X            if (hold)
  123. X                write_vs(vs_file, max_row, max_col);
  124. X            break;
  125. X        case 4:            /* cleanup and go home */
  126. X            signal(SIGTERM, got_sig);
  127. X            if (log)
  128. X                fclose(logfp);
  129. X            if (print) {
  130. X                putc(014, lprfp);
  131. X                pclose(lprfp);
  132. X            }
  133. X            _exit(0);
  134. X            break;
  135. X    }
  136. X                    /* any signal will awaken pause() */
  137. X    if (hold)
  138. X        pause();
  139. X                    /* clear if vs_path doesn't exist */
  140. X    if (access(vs_file, 0))
  141. X        clear_vs(max_row, max_col);
  142. X    /*
  143. X     * The very first screen we see after dialing has the "Connected to..."
  144. X     * message at row 0, therefore we start our virtual screen at row 1.
  145. X     */
  146. X    if (skip_row) {
  147. X        skip_row = 0;
  148. X        row = 1;
  149. X    }
  150. X
  151. X    while(1) {
  152. X        if (read(fd, (char *) &c, 1) <= 0)
  153. X            continue;
  154. X                    /* send to logfile */
  155. X        if (log) {
  156. X            if (c == 015 && add_lf)
  157. X                fwrite(&lf, 1, 1, logfp);
  158. X                    /* no carriage returns in logfile */
  159. X            if (c != 015)
  160. X                fwrite((char *) &c, 1, 1, logfp);
  161. X        }
  162. X                    /* send to printer too ? */
  163. X        if (print)
  164. X            fwrite((char *) &c, 1, 1, lprfp);
  165. X
  166. X                    /* put a char in virtual screen */
  167. X        putchar_vs(c, add_lf, max_row, max_col);
  168. X
  169. X        write(1, (char *) &c, 1);
  170. X                    /* add LF to CR ? */
  171. X        if (add_lf)
  172. X            write(1, &lf, 1);
  173. X    }
  174. X}
  175. X
  176. X/*
  177. X * Figure out which signal we just received, and fix the return code of
  178. X * the setjmp function above to the proper value.
  179. X */
  180. X
  181. Xint
  182. Xgot_sig(sig)
  183. Xint sig;
  184. X{
  185. X    void longjmp();
  186. X
  187. X    switch(sig) {
  188. X        case SIGUSR1:
  189. X            longjmp(i_jmp, 1);
  190. X        case SIGUSR2:
  191. X            longjmp(i_jmp, 2);
  192. X        case SIGINT:
  193. X            longjmp(i_jmp, 3);
  194. X        case SIGTERM:
  195. X            longjmp(i_jmp, 4);
  196. X    }
  197. X}
  198. X
  199. X/*
  200. X * Put a character in the virtual screen.  This routine saves incoming
  201. X * character in a two dimensional buffer designed to mimic the real
  202. X * screen.  CURRENTLY DOES NOT UNDERSTAND ESCAPE SEQUENCES!
  203. X */
  204. X
  205. Xint
  206. Xputchar_vs(c, add_lf, max_row, max_col)
  207. Xunsigned char c;
  208. Xint add_lf, max_row, max_col;
  209. X{
  210. X    int tab_stop;
  211. X
  212. X    switch(c) {
  213. X        case 8:            /* destructive back space */
  214. X            col--;
  215. X            if (col < 0)
  216. X                col = 0;
  217. X            vs[row][col] = ' ';
  218. X            break;
  219. X        case 9:            /* tab character */
  220. X            tab_stop = col + 8 - (col % 8);
  221. X                    /* if wrap around */
  222. X            if (tab_stop >= max_col) {
  223. X                    /* spaces up to eol */
  224. X                for (; col<max_col; col++)
  225. X                    vs[row][col] = ' ';
  226. X                row++;
  227. X                if (row >= max_row)
  228. X                    scroll_vs(max_row, max_col);
  229. X
  230. X                    /* the remainder of the tab */
  231. X                col = tab_stop - max_col;
  232. X            }
  233. X            else {
  234. X                for (; col<tab_stop; col++)
  235. X                    vs[row][col] = ' ';
  236. X            }
  237. X            break;
  238. X        case 13:        /* carriage return */
  239. X            col = 0;
  240. X            if (!add_lf)
  241. X                break;
  242. X            /* fall thru...*/
  243. X        case 10:        /* line feed */
  244. X            row++;
  245. X            if (row >= max_row)
  246. X                scroll_vs(max_row, max_col);
  247. X            break;
  248. X        default:        /* a normal character */
  249. X            vs[row][col] = c;
  250. X            col++;
  251. X                    /* wrap around */
  252. X            if (col >= max_col) {
  253. X                col = 0;
  254. X                row++;
  255. X                if (row >= max_row)
  256. X                    scroll_vs(max_row, max_col);
  257. X            }
  258. X            break;
  259. X    }
  260. X    return;
  261. X}
  262. X
  263. X/*
  264. X * Save the virtual screen to a file.
  265. X */
  266. X
  267. Xint
  268. Xwrite_vs(vs_file, max_row, max_col)
  269. Xchar *vs_file;
  270. Xint max_row, max_col;
  271. X{
  272. X    FILE *fp;
  273. X    int i;
  274. X
  275. X    if (!(fp = fopen(vs_file, "w")))
  276. X        return(1);
  277. X                    /* current x y coordinates */
  278. X    fprintf(fp, "%d,%d\n", row, col);
  279. X
  280. X    for (i=0; i<max_row; i++) {
  281. X        vs[i][max_col] = NULL;
  282. X        fprintf(fp, "%s\n", vs[i]);
  283. X    }
  284. X    fclose(fp);
  285. X    return(0);
  286. X}
  287. X
  288. X/*
  289. X * Get the virtual screen image from the file.  Since input() gets
  290. X * killed from time to time, the vs_path file is the only way to retain
  291. X * the screen image.
  292. X */
  293. X
  294. Xint
  295. Xread_vs(vs_file, max_row, max_col)
  296. Xchar *vs_file;
  297. Xint max_row, max_col;
  298. X{
  299. X    FILE *fp;
  300. X    int i;
  301. X    char buf[10];
  302. X                /* in case the fopen fails... */
  303. X    row = 0;
  304. X    col = 0;
  305. X                /* not guaranteed to exist yet */
  306. X    if (!(fp = fopen(vs_file, "r")))
  307. X        return(1);
  308. X                /* get the x, y coordinates */
  309. X    fgets(buf, 10, fp);
  310. X    scanf(buf, "%d,%d\n", &row, &col);
  311. X
  312. X                /* read the file into the vs array */
  313. X    for (i=0; i<max_row; i++) {
  314. X        fgets((char *) vs[i], MAX_COL+2, fp);
  315. X        vs[i][max_col] = NULL;
  316. X    }
  317. X
  318. X    fclose(fp);
  319. X    return(0);
  320. X}
  321. X
  322. X/*
  323. X * If the user clears the screen with the ^A-C command, the input
  324. X * has to be in sync.  The way it gets notified, is that the vs_path
  325. X * file disappears.
  326. X */
  327. X
  328. Xint
  329. Xclear_vs(max_row, max_col)
  330. Xint max_row, max_col;
  331. X{
  332. X    int i, j;
  333. X
  334. X    for (i=0; i<max_row; i++) {
  335. X        vs[i][max_col] = NULL;
  336. X        for (j=0; j<max_col; j++)
  337. X            vs[i][j] = ' ';
  338. X    }
  339. X                    /* home the "cursor" */
  340. X    row = 0;
  341. X    col = 0;
  342. X    return(0);
  343. X}
  344. X
  345. X/*
  346. X * Do a software scroll on the virtual screen.  Does not alter the
  347. X * 'col' variable.
  348. X */
  349. X
  350. Xint
  351. Xscroll_vs(max_row, max_col)
  352. Xint max_row, max_col;
  353. X{
  354. X    int i, j;
  355. X    char *strcpy();
  356. X                    /* move 'em up 1 line */
  357. X    for (i=0; i<max_row-1; i++)
  358. X        strcpy((char *) vs[i], (char *) vs[i+1]);
  359. X                    /* clear the bottom line */
  360. X    for (j=0; j<max_col; j++)
  361. X        vs[max_row-1][j] = ' ';
  362. X
  363. X    row = max_row -1;
  364. X    return(0);
  365. X}
  366. SHAR_EOF
  367. if test 6599 -ne "`wc -c < 'input.c'`"
  368. then
  369.     echo shar: "error transmitting 'input.c'" '(should have been 6599 characters)'
  370. fi
  371. fi
  372. echo shar: "extracting 'line_set.c'" '(2130 characters)'
  373. if test -f 'line_set.c'
  374. then
  375.     echo shar: "will not over-write existing file 'line_set.c'"
  376. else
  377. sed 's/^X//' << \SHAR_EOF > 'line_set.c'
  378. X/*
  379. X * Change the communication line settings to the new values.
  380. X */
  381. X
  382. X#include <stdio.h>
  383. X#include <termio.h>
  384. X#include "dial_dir.h"
  385. X#include "param.h"
  386. X#include "status.h"
  387. X
  388. Xvoid
  389. Xline_set()
  390. X{
  391. X    struct termio tbuf;
  392. X
  393. X    /*
  394. X     * The manual dial entry also serves to store the previous
  395. X     * line settings.  How else would the manual dial entry
  396. X     * know what line setting to use?
  397. X     */
  398. X    if (dir->d_cur != 0) {
  399. X        dir->baud[0] = dir->baud[dir->d_cur];
  400. X        dir->parity[0] = dir->parity[dir->d_cur];
  401. X        dir->dbits[0] = dir->dbits[dir->d_cur];
  402. X        dir->sbits[0] = dir->sbits[dir->d_cur];
  403. X    }
  404. X                    /* nothing to do! */
  405. X    if (status->fd == -1)
  406. X        return;
  407. X                    /* get the current settings */
  408. X    ioctl(status->fd, TCGETA, &tbuf);
  409. X                    /* set some beginning values */
  410. X    tbuf.c_cc[4] = 1;
  411. X    tbuf.c_cc[5] = 0;
  412. X    tbuf.c_oflag = 0;
  413. X    tbuf.c_iflag = 0;
  414. X    tbuf.c_cflag = (CREAD|HUPCL);
  415. X    tbuf.c_lflag = 0;
  416. X
  417. X    /*
  418. X     * I don't think there's any need for output flow control... (I don't
  419. X     * know about you guys, but I can't type faster than the host can
  420. X     * receive!)  Besides, the file transfers reset this anyway.
  421. X     */
  422. X    if (*param->flow == 'X')
  423. X        tbuf.c_iflag |= IXOFF;
  424. X                    /* strip high bit ? */
  425. X    if (*param->strip == 'Y')
  426. X        tbuf.c_iflag |= ISTRIP;
  427. X                    /* the baud rate */
  428. X    switch (dir->baud[dir->d_cur]) {
  429. X        case 300:
  430. X            tbuf.c_cflag |= B300;
  431. X            break;
  432. X        case 1200:
  433. X            tbuf.c_cflag |= B1200;
  434. X            break;
  435. X        case 2400:
  436. X            tbuf.c_cflag |= B2400;
  437. X            break;
  438. X        case 4800:
  439. X            tbuf.c_cflag |= B4800;
  440. X            break;
  441. X        case 9600:
  442. X            tbuf.c_cflag |= B9600;
  443. X            break;
  444. X        case 19200:
  445. X            /*
  446. X             * Be careful here... some systems use EXTA in lieu
  447. X             * of B19200.
  448. X             */
  449. X            tbuf.c_cflag |= B19200;
  450. X            break;
  451. X    }
  452. X                    /* the parity */
  453. X    switch (dir->parity[dir->d_cur]) {
  454. X        case 'N':
  455. X            break;
  456. X        case 'O':
  457. X            tbuf.c_cflag |= (PARENB|PARODD);
  458. X            break;
  459. X        case 'E':
  460. X            tbuf.c_cflag |= PARENB;
  461. X            break;
  462. X    }
  463. X                    /* the data bits */
  464. X    if (dir->dbits[dir->d_cur] == 8)
  465. X        tbuf.c_cflag |= CS8;
  466. X    else
  467. X        tbuf.c_cflag |= CS7;
  468. X                    /* the stop bits */
  469. X    if (dir->sbits[dir->d_cur] == 2)
  470. X        tbuf.c_cflag |= CSTOPB;
  471. X
  472. X                    /* now set 'em! */
  473. X    ioctl(status->fd, TCSETA, &tbuf);
  474. X    ioctl(status->fd, TCFLSH, 2);
  475. X    return;
  476. X}
  477. SHAR_EOF
  478. if test 2130 -ne "`wc -c < 'line_set.c'`"
  479. then
  480.     echo shar: "error transmitting 'line_set.c'" '(should have been 2130 characters)'
  481. fi
  482. fi
  483. echo shar: "extracting 'list_dir.c'" '(1479 characters)'
  484. if test -f 'list_dir.c'
  485. then
  486.     echo shar: "will not over-write existing file 'list_dir.c'"
  487. else
  488. sed 's/^X//' << \SHAR_EOF > 'list_dir.c'
  489. X/*
  490. X * Do a shell escape with an 'ls' command
  491. X */
  492. X
  493. X#include <stdio.h>
  494. X#include <curses.h>
  495. X#include "misc.h"
  496. X
  497. Xvoid
  498. Xlist_dir(fd)
  499. Xint fd;
  500. X{
  501. X    WINDOW *ls_win, *newwin();
  502. X    FILE *pfp, *native_popen();
  503. X    int lines, oops;
  504. X    char *ans, *cwd, *getcwd(), buf[200], *get_str();
  505. X
  506. X    ls_win = newwin(6, 70, 8, 5);
  507. X
  508. X    cwd = getcwd(buf, 200);
  509. X
  510. X    mvwprintw(ls_win, 2, 4, "Current directory: %s", cwd);
  511. X    mvwaddstr(ls_win, 3, 4, "File spec (wildcards allowed): ");
  512. X    box(ls_win, '|', '-');
  513. X
  514. X    mvwattrstr(ls_win, 0, 3, A_BOLD, " List Directory ");
  515. X    wmove(ls_win, 3, 35);
  516. X    wrefresh(ls_win);
  517. X
  518. X    if ((ans = get_str(ls_win, 60, NULL, NULL)) == NULL) {
  519. X        if (fd == -1) {
  520. X            werase(ls_win);
  521. X            wrefresh(ls_win);
  522. X        }
  523. X        delwin(ls_win);
  524. X        return;
  525. X    }
  526. X                    /* popen() an ls */
  527. X    sprintf(buf, "ls -aC %s", ans);
  528. X    pfp = native_popen(buf, "r");
  529. X                    /* make a bigger window */
  530. X    werase(ls_win);
  531. X    wrefresh(ls_win);
  532. X    delwin(ls_win);
  533. X    ls_win = newwin(LINES-1, COLS, 0, 0);
  534. X
  535. X    oops = 0;
  536. X    lines = 0;
  537. X    while (fgets(buf, BUFSIZ, pfp) != NULL) {
  538. X        waddstr(ls_win, buf);
  539. X        lines++;
  540. X        if (lines == LINES-2) {
  541. X            lines = 0;
  542. X            mvwaddstr(ls_win, LINES-2, 28, "Press any key for more");
  543. X            wrefresh(ls_win);
  544. X            if (wgetch(ls_win) == 27) {
  545. X                oops++;
  546. X                break;
  547. X            }
  548. X            werase(ls_win);
  549. X            wrefresh(ls_win);
  550. X        }
  551. X    }
  552. X    native_pclose(pfp);
  553. X
  554. X    if (!oops) {
  555. X        mvwaddstr(ls_win, LINES-2, 25, "Press any key to continue");
  556. X        wrefresh(ls_win);
  557. X        wgetch(ls_win);
  558. X    }
  559. X    if (fd == -1) {
  560. X        werase(ls_win);
  561. X        wrefresh(ls_win);
  562. X    }
  563. X    delwin(ls_win);
  564. X    return;
  565. X}
  566. SHAR_EOF
  567. if test 1479 -ne "`wc -c < 'list_dir.c'`"
  568. then
  569.     echo shar: "error transmitting 'list_dir.c'" '(should have been 1479 characters)'
  570. fi
  571. fi
  572. echo shar: "extracting 'ls_menu.c'" '(4820 characters)'
  573. if test -f 'ls_menu.c'
  574. then
  575.     echo shar: "will not over-write existing file 'ls_menu.c'"
  576. else
  577. sed 's/^X//' << \SHAR_EOF > 'ls_menu.c'
  578. X/*
  579. X * Routines for displaying current line settings and prompting for changes.
  580. X */
  581. X
  582. X#include <stdio.h>
  583. X#include <curses.h>
  584. X#include "dial_dir.h"
  585. X#include "misc.h"
  586. X#include "param.h"
  587. X
  588. X/*
  589. X * Display the current line settings and prompt for changes.  A return
  590. X * code of 1 means settings were changed.
  591. X */
  592. X
  593. Xint
  594. Xline_set_menu(fd)
  595. Xint fd;
  596. X{
  597. X    WINDOW *l_win, *newwin();
  598. X    int num, ret_code;
  599. X    void disp_settings();
  600. X
  601. X    l_win = newwin(20, 47, 0, 16);
  602. X
  603. X    mvwattrstr(l_win, 1, 16, A_BOLD, "Line Settings");
  604. X    waddstr(l_win, "\n----------------------------------------------");
  605. X    mvwaddstr(l_win, 6, 5, "1)     300,E,7,1     7)     300,N,8,1");
  606. X    mvwaddstr(l_win, 7, 5, "2)    1200,E,7,1     8)    1200,N,8,1");
  607. X    mvwaddstr(l_win, 8, 5, "3)    2400,E,7,1     9)    2400,N,8,1");
  608. X    mvwaddstr(l_win, 9, 5, "4)    4800,E,7,1    10)    4800,N,8,1");
  609. X    mvwaddstr(l_win, 10, 5, "5)    9600,E,7,1    11)    9600,N,8,1");
  610. X    mvwaddstr(l_win, 11, 5, "6)   19200,E,7,1    12)   19200,N,8,1");
  611. X    mvwaddstr(l_win, 13, 4, "Parity        Data Bits       Stop Bits");
  612. X    mvwaddstr(l_win, 14, 4, "13) Odd       14) 7 bits      16) 1 bit");
  613. X    mvwaddstr(l_win, 15, 18, "15) 8 bits      17) 2 bits");
  614. X    mvwaddstr(l_win, 17, 4, "18) Save Changes");
  615. X    mvwattrstr(l_win, 17, 28, A_BOLD, "YOUR CHOICE:");
  616. X    wmove(l_win, 17, 41);
  617. X    box(l_win, '|', '-');
  618. X
  619. X    mvwaddstr(l_win, 19, 14, " Press ESC to return ");
  620. X                    /* display current settings */
  621. X    disp_settings(l_win);
  622. X    wmove(l_win, 17, 41);
  623. X    wrefresh(l_win);
  624. X                    /* get the options */
  625. X    ret_code = 0;
  626. X    while ((num = get_num(l_win, 2)) != -1) {
  627. X        switch(num) {
  628. X            case 1:
  629. X                dir->baud[dir->d_cur] = 300;
  630. X                dir->parity[dir->d_cur] = 'E';
  631. X                dir->dbits[dir->d_cur] = 7;
  632. X                dir->sbits[dir->d_cur] = 1;
  633. X                break;
  634. X            case 2:
  635. X                dir->baud[dir->d_cur] = 1200;
  636. X                dir->parity[dir->d_cur] = 'E';
  637. X                dir->dbits[dir->d_cur] = 7;
  638. X                dir->sbits[dir->d_cur] = 1;
  639. X                break;
  640. X            case 3:
  641. X                dir->baud[dir->d_cur] = 2400;
  642. X                dir->parity[dir->d_cur] = 'E';
  643. X                dir->dbits[dir->d_cur] = 7;
  644. X                dir->sbits[dir->d_cur] = 1;
  645. X                break;
  646. X            case 4:
  647. X                dir->baud[dir->d_cur] = 4800;
  648. X                dir->parity[dir->d_cur] = 'E';
  649. X                dir->dbits[dir->d_cur] = 7;
  650. X                dir->sbits[dir->d_cur] = 1;
  651. X                break;
  652. X            case 5:
  653. X                dir->baud[dir->d_cur] = 9600;
  654. X                dir->parity[dir->d_cur] = 'E';
  655. X                dir->dbits[dir->d_cur] = 7;
  656. X                dir->sbits[dir->d_cur] = 1;
  657. X                break;
  658. X            case 6:
  659. X                dir->baud[dir->d_cur] = 19200;
  660. X                dir->parity[dir->d_cur] = 'E';
  661. X                dir->dbits[dir->d_cur] = 7;
  662. X                dir->sbits[dir->d_cur] = 1;
  663. X                break;
  664. X            case 7:
  665. X                dir->baud[dir->d_cur] = 300;
  666. X                dir->parity[dir->d_cur] = 'N';
  667. X                dir->dbits[dir->d_cur] = 8;
  668. X                dir->sbits[dir->d_cur] = 1;
  669. X                break;
  670. X            case 8:
  671. X                dir->baud[dir->d_cur] = 1200;
  672. X                dir->parity[dir->d_cur] = 'N';
  673. X                dir->dbits[dir->d_cur] = 8;
  674. X                dir->sbits[dir->d_cur] = 1;
  675. X                break;
  676. X            case 9:
  677. X                dir->baud[dir->d_cur] = 2400;
  678. X                dir->parity[dir->d_cur] = 'N';
  679. X                dir->dbits[dir->d_cur] = 8;
  680. X                dir->sbits[dir->d_cur] = 1;
  681. X                break;
  682. X            case 10:
  683. X                dir->baud[dir->d_cur] = 4800;
  684. X                dir->parity[dir->d_cur] = 'N';
  685. X                dir->dbits[dir->d_cur] = 8;
  686. X                dir->sbits[dir->d_cur] = 1;
  687. X                break;
  688. X            case 11:
  689. X                dir->baud[dir->d_cur] = 9600;
  690. X                dir->parity[dir->d_cur] = 'N';
  691. X                dir->dbits[dir->d_cur] = 8;
  692. X                dir->sbits[dir->d_cur] = 1;
  693. X                break;
  694. X            case 12:
  695. X                dir->baud[dir->d_cur] = 19200;
  696. X                dir->parity[dir->d_cur] = 'N';
  697. X                dir->dbits[dir->d_cur] = 8;
  698. X                dir->sbits[dir->d_cur] = 1;
  699. X                break;
  700. X            case 13:
  701. X                dir->parity[dir->d_cur] = 'O';
  702. X                break;
  703. X            case 14:
  704. X                dir->dbits[dir->d_cur] = 7;
  705. X                break;
  706. X            case 15:
  707. X                dir->dbits[dir->d_cur] = 8;
  708. X                break;
  709. X            case 16:
  710. X                dir->sbits[dir->d_cur] = 1;
  711. X                break;
  712. X            case 17:
  713. X                dir->sbits[dir->d_cur] = 2;
  714. X                break;
  715. X            case 18:
  716. X                    /* copy the current settings */
  717. X                param->d_baud = dir->baud[dir->d_cur];
  718. X                param->d_parity = dir->parity[dir->d_cur];
  719. X                param->d_dbits = dir->dbits[dir->d_cur];
  720. X                param->d_sbits = dir->sbits[dir->d_cur];
  721. X                /*
  722. X                 * We've changed the values in memory even
  723. X                 * if the update fails.
  724. X                 */
  725. X                if (update_param()) {
  726. X                    touchwin(l_win);
  727. X                    wrefresh(l_win);
  728. X                }
  729. X                break;
  730. X            default:
  731. X                beep();
  732. X        }
  733. X        ret_code++;
  734. X        disp_settings(l_win);
  735. X        mvwaddstr(l_win, 17, 41, "    ");
  736. X        wmove(l_win, 17, 41);
  737. X        wrefresh(l_win);
  738. X    }
  739. X    if (fd == -1) {
  740. X        werase(l_win);
  741. X        wrefresh(l_win);
  742. X    }
  743. X    delwin(l_win);
  744. X    return(ret_code);
  745. X}
  746. X
  747. X/*
  748. X * Display the current settings.  Formats the entire string at one
  749. X * time, in case you've got a magic cookie terminal.
  750. X */
  751. X
  752. Xvoid
  753. Xdisp_settings(win)
  754. XWINDOW *win;
  755. X{
  756. X    char buf[40];
  757. X    extern int xmc;
  758. X
  759. X    sprintf(buf, "Current Settings: %5d,%c,%d,%d", dir->baud[dir->d_cur],
  760. X     dir->parity[dir->d_cur], dir->dbits[dir->d_cur],
  761. X     dir->sbits[dir->d_cur]);
  762. X
  763. X    if (xmc > 0) {
  764. X        touchwin(win);
  765. X        clear_line(win, 4, 8, 1);
  766. X        wrefresh(win);
  767. X    }
  768. X    mvwattrstr(win, 4, 8, A_BOLD, buf);
  769. X    return;
  770. X}
  771. SHAR_EOF
  772. if test 4820 -ne "`wc -c < 'ls_menu.c'`"
  773. then
  774.     echo shar: "error transmitting 'ls_menu.c'" '(should have been 4820 characters)'
  775. fi
  776. fi
  777. echo shar: "extracting 'm_lib.c'" '(9489 characters)'
  778. if test -f 'm_lib.c'
  779. then
  780.     echo shar: "will not over-write existing file 'm_lib.c'"
  781. else
  782. sed 's/^X//' << \SHAR_EOF > 'm_lib.c'
  783. X/*
  784. X * Routines to manipulate the pcomm.modem file
  785. X */
  786. X
  787. X#include <stdio.h>
  788. X#include "modem.h"
  789. X#include "status.h"
  790. X
  791. X/*
  792. X * Read the modem database file.  Returns a pointer to a static area
  793. X * containing the MODEM structure.  All modem entries and all tty entries
  794. X * are created reguardless of the number of physical entries in the file.
  795. X */
  796. X
  797. Xstruct MODEM *
  798. Xread_modem()
  799. X{
  800. X    FILE *fp;
  801. X    int i, tty, mod, line, oops, m_line, start, stop;
  802. X    char *strdup(), buf[200], message[80], token[40], *str_tok(), *str;
  803. X    char *temp_token, *t_sep, *m_sep, *m_letter;
  804. X    static struct MODEM m;
  805. X    void error_win();
  806. X    extern char *null_ptr;
  807. X
  808. X    if (!(fp = fopen(status->m_path, "r"))) {
  809. X        sprintf(buf, "'%s' for read", status->m_path);
  810. X        error_win(1, "Can't open modem file", buf);
  811. X    }
  812. X
  813. X    t_sep = ";;\n";
  814. X    m_sep = ";;;;\n;;;;;\n;;;\n";
  815. X    m_letter = "abc";
  816. X    oops = 0;
  817. X    tty = 0;
  818. X    mod = 0;
  819. X    line = 0;
  820. X    m_line = 0;
  821. X    while (fgets(buf, 200, fp) != NULL) {
  822. X        line++;
  823. X        if (tty >= NUM_TTY || mod >= NUM_MODEM)
  824. X            break;
  825. X                    /* get the token */
  826. X        if (!(temp_token = str_tok(buf, '='))) {
  827. X            sprintf(message, "is missing a token at line %d", line);
  828. X            oops++;
  829. X            break;
  830. X        }
  831. X        if (*temp_token != 'T' && *temp_token != 'M') {
  832. X            sprintf(message, "is corrupted at line %d", line);
  833. X            oops++;
  834. X            break;
  835. X        }
  836. X                    /* the tty database */
  837. X        if (*temp_token == 'T') {
  838. X            /*
  839. X             * This is similar to the "real" strtok() command
  840. X             * but this one returns a null pointer on a missing
  841. X             * attribute.  Note the use of the field separator
  842. X             * array.
  843. X             */
  844. X            for (i=0; i<3; i++) {
  845. X                if (!(str = str_tok((char *) NULL, t_sep[i]))) {
  846. X                    sprintf(message, "is missing a parameter at line %d", line);
  847. X                    oops++;
  848. X                    break;
  849. X                }
  850. X                switch(i) {    
  851. X                    case 0:
  852. X                        m.tty[tty] = strdup(str);
  853. X                        break;
  854. X                    case 1:
  855. X                        m.tname[tty] = strdup(str);
  856. X                        break;
  857. X                    case 2:
  858. X                        m.mbaud[tty] = atoi(str);
  859. X                        break;
  860. X                }
  861. X            }
  862. X            if (oops)
  863. X                break;
  864. X                    /* sanity checking */
  865. X            sprintf(token, "TTY_%d", tty+1);
  866. X            if (strcmp(token, temp_token)) {
  867. X                sprintf(message, "is corrupted at line %d", line);
  868. X                oops++;
  869. X                break;
  870. X            }
  871. X            tty++;
  872. X            continue;
  873. X        }
  874. X                    /* the modem database */
  875. X        else {
  876. X            sprintf(token, "MODEM_%d%c", mod+1, m_letter[m_line]);
  877. X            if (strcmp(token, temp_token)) {
  878. X                sprintf(message, "is corrupted at line %d", line);
  879. X                oops++;
  880. X                break;
  881. X            }
  882. X            /*
  883. X             * There are three lines to the modem database.  They
  884. X             * distinguished by the letters a, b, and, c appended
  885. X             * to the entry number.
  886. X             */
  887. X            switch(m_line) {
  888. X                case 0:
  889. X                    start = 0;
  890. X                    stop = 5;
  891. X                    break;
  892. X                case 1:
  893. X                    start = 5;
  894. X                    stop = 11;
  895. X                    break;
  896. X                case 2:
  897. X                    start = 11;
  898. X                    stop = 15;
  899. X                    break;
  900. X            }
  901. X            for (i=start; i<stop; i++) {
  902. X                if (!(str = str_tok((char *) NULL, m_sep[i]))) {
  903. X                    sprintf(message, "is missing a parameter at line %d", line);
  904. X                    oops++;
  905. X                    break;
  906. X                }
  907. X                switch(i) {
  908. X                    case 0:
  909. X                        m.mname[mod] = strdup(str);
  910. X                        break;
  911. X                    case 1:
  912. X                        m.init[mod] = strdup(str);
  913. X                        break;
  914. X                    case 2:
  915. X                        m.dial[mod] = strdup(str);
  916. X                        break;
  917. X                    case 3:
  918. X                        m.suffix[mod] = strdup(str);
  919. X                        break;
  920. X                    case 4:
  921. X                        m.hangup[mod] = strdup(str);
  922. X                        break;
  923. X                    case 5:
  924. X                        m.con_3[mod] = strdup(str);
  925. X                        break;
  926. X                    case 6:
  927. X                        m.con_12[mod] = strdup(str);
  928. X                        break;
  929. X                    case 7:
  930. X                        m.con_24[mod] = strdup(str);
  931. X                        break;
  932. X                    case 8:
  933. X                        m.con_48[mod] = strdup(str);
  934. X                        break;
  935. X                    case 9:
  936. X                        m.con_96[mod] = strdup(str);
  937. X                        break;
  938. X                    case 10:
  939. X                        m.con_192[mod] = strdup(str);
  940. X                        break;
  941. X                    case 11:
  942. X                        m.no_con1[mod] = strdup(str);
  943. X                        break;
  944. X                    case 12:
  945. X                        m.no_con2[mod] = strdup(str);
  946. X                        break;
  947. X                    case 13:
  948. X                        m.no_con3[mod] = strdup(str);
  949. X                        break;
  950. X                    case 14:
  951. X                        m.no_con4[mod] = strdup(str);
  952. X                        break;
  953. X                }
  954. X            }
  955. X            if (oops)
  956. X                break;
  957. X            m_line++;
  958. X            if (m_line >= 3) {
  959. X                m_line = 0;
  960. X                mod++;
  961. X            }
  962. X        }
  963. X    }
  964. X    fclose(fp);
  965. X
  966. X    if (oops) {
  967. X        sprintf(buf, "Modem file '%s'", status->m_path);
  968. X        error_win(1, buf, message);
  969. X    }
  970. X    m.t_entries = tty;
  971. X    m.m_entries = mod;
  972. X    m.t_cur = -1;
  973. X    m.m_cur = -1;
  974. X                    /* fill in the rest */
  975. X    for (; tty<NUM_TTY; tty++) {
  976. X        m.tty[tty] = null_ptr;
  977. X        m.tname[tty] = null_ptr;
  978. X        m.mbaud[tty] = 0;
  979. X    }
  980. X    for (; mod<NUM_MODEM; mod++) {
  981. X        m.mname[mod] = null_ptr;
  982. X        m.init[mod] = null_ptr;
  983. X        m.dial[mod] = null_ptr;
  984. X        m.suffix[mod] = null_ptr;
  985. X        m.hangup[mod] = null_ptr;
  986. X
  987. X        m.con_3[mod] = null_ptr;
  988. X        m.con_12[mod] = null_ptr;
  989. X        m.con_24[mod] = null_ptr;
  990. X        m.con_48[mod] = null_ptr;
  991. X        m.con_96[mod] = null_ptr;
  992. X        m.con_192[mod] = null_ptr;
  993. X
  994. X        m.no_con1[mod] = null_ptr;
  995. X        m.no_con2[mod] = null_ptr;
  996. X        m.no_con3[mod] = null_ptr;
  997. X        m.no_con4[mod] = null_ptr;
  998. X    }
  999. X    return(&m);
  1000. X}
  1001. X
  1002. X/*
  1003. X * Update the modem database.  Other routines actually do the changes
  1004. X * or deletions in memory.  A return code of 1 means non-fatal error.
  1005. X */
  1006. X
  1007. Xint
  1008. Xupdate_modem()
  1009. X{
  1010. X    FILE *fp;
  1011. X    char buf[80];
  1012. X    int i;
  1013. X    void error_win();
  1014. X
  1015. X                    /* open for write */
  1016. X    if (!(fp = fopen(status->m_path, "w"))) {
  1017. X        sprintf(buf, "'%s'", status->m_path);
  1018. X        error_win(0, "No write permission on modem file", buf);
  1019. X        return(1);
  1020. X    }
  1021. X                    /* put back the tty entries */
  1022. X    for (i=0; i<modem->t_entries; i++)
  1023. X        fprintf(fp, "TTY_%d=%s;%s;%d\n", i+1, modem->tty[i],
  1024. X         modem->tname[i], modem->mbaud[i]);
  1025. X
  1026. X                    /* put back the modem entries */
  1027. X    for (i=0; i<modem->m_entries; i++) {
  1028. X        fprintf(fp, "MODEM_%da=%s;%s;%s;%s;%s\n", i+1, modem->mname[i],
  1029. X         modem->init[i], modem->dial[i], modem->suffix[i],
  1030. X         modem->hangup[i]);
  1031. X
  1032. X        fprintf(fp, "MODEM_%db=%s;%s;%s;%s;%s;%s\n", i+1,
  1033. X         modem->con_3[i], modem->con_12[i], modem->con_24[i],
  1034. X         modem->con_48[i], modem->con_96[i], modem->con_192[i]);
  1035. X
  1036. X        fprintf(fp, "MODEM_%dc=%s;%s;%s;%s\n", i+1, modem->no_con1[i],
  1037. X         modem->no_con2[i], modem->no_con3[i], modem->no_con4[i]);
  1038. X    }
  1039. X
  1040. X    fclose(fp);
  1041. X    return(0);
  1042. X}
  1043. X
  1044. X/*
  1045. X * See if the new modem is already in the database.  If it's not,
  1046. X * then create a slot for it and update the modem->m_cur variable.
  1047. X */
  1048. X
  1049. Xvoid
  1050. Xcreate_modem(str)
  1051. Xchar *str;
  1052. X{
  1053. X    int i;
  1054. X    char *strdup(), buf[80];
  1055. X    void error_win(), free_ptr();
  1056. X                    /* modem entry already exists? */
  1057. X    for (i=0; i<modem->m_entries; i++) {
  1058. X        if (!strcmp(str, modem->mname[i]))
  1059. X            return;
  1060. X    }
  1061. X                    /* empty slot available? */
  1062. X    if (modem->m_entries == NUM_MODEM) {
  1063. X        sprintf(buf, "'%s'", status->m_path);
  1064. X        error_win(0, "No empty modem slots in", buf);
  1065. X        return;
  1066. X    }
  1067. X                    /* create a new entry */
  1068. X    free_ptr(modem->mname[modem->m_entries]);
  1069. X    modem->mname[modem->m_entries] = strdup(str);
  1070. X
  1071. X                    /* update number of entries */
  1072. X    modem->m_entries++;
  1073. X    return;
  1074. X}
  1075. X
  1076. X/*
  1077. X * See if the modem names in the list still need to be in the database.
  1078. X * If you find a "lost" entry, delete it and collapse the list.
  1079. X */
  1080. X
  1081. Xvoid
  1082. Xdelete_modem()
  1083. X{
  1084. X    int i, j, match;
  1085. X    char *strdup();
  1086. X    void free_ptr();
  1087. X    extern char *null_ptr;
  1088. X
  1089. X    for (i=0; i<modem->m_entries; i++) {
  1090. X        match = 0;
  1091. X        for (j=0; j<modem->t_entries; j++) {
  1092. X            if (!strcmp(modem->mname[i], modem->tname[j])) {
  1093. X                match = 1;
  1094. X                break;
  1095. X            }
  1096. X        }
  1097. X                    /* found a "lost" modem name */
  1098. X        if (!match) {
  1099. X            for (j=i; j<modem->m_entries-1; j++) {
  1100. X                free_ptr(modem->mname[j]);
  1101. X                free_ptr(modem->init[j]);
  1102. X                free_ptr(modem->dial[j]);
  1103. X                free_ptr(modem->suffix[j]);
  1104. X                free_ptr(modem->hangup[j]);
  1105. X
  1106. X                free_ptr(modem->con_3[j]);
  1107. X                free_ptr(modem->con_12[j]);
  1108. X                free_ptr(modem->con_24[j]);
  1109. X                free_ptr(modem->con_48[j]);
  1110. X                free_ptr(modem->con_96[j]);
  1111. X                free_ptr(modem->con_192[j]);
  1112. X
  1113. X                free_ptr(modem->no_con1[j]);
  1114. X                free_ptr(modem->no_con2[j]);
  1115. X                free_ptr(modem->no_con3[j]);
  1116. X                free_ptr(modem->no_con4[j]);
  1117. X
  1118. X                    /* copy the info */
  1119. X                modem->mname[j] = strdup(modem->mname[j+1]);
  1120. X                modem->init[j] = strdup(modem->init[j+1]);
  1121. X                modem->dial[j] = strdup(modem->dial[j+1]);
  1122. X                modem->suffix[j] = strdup(modem->suffix[j+1]);
  1123. X                modem->hangup[j] = strdup(modem->hangup[j+1]);
  1124. X
  1125. X                modem->con_3[j] = strdup(modem->con_3[j+1]);
  1126. X                modem->con_12[j] = strdup(modem->con_12[j+1]);
  1127. X                modem->con_24[j] = strdup(modem->con_24[j+1]);
  1128. X                modem->con_48[j] = strdup(modem->con_48[j+1]);
  1129. X                modem->con_96[j] = strdup(modem->con_96[j+1]);
  1130. X                modem->con_192[j] = strdup(modem->con_192[j+1]);
  1131. X
  1132. X                modem->no_con1[j] = strdup(modem->no_con1[j+1]);
  1133. X                modem->no_con2[j] = strdup(modem->no_con2[j+1]);
  1134. X                modem->no_con3[j] = strdup(modem->no_con3[j+1]);
  1135. X                modem->no_con4[j] = strdup(modem->no_con4[j+1]);
  1136. X            }
  1137. X            j = modem->m_entries -1;
  1138. X
  1139. X            free_ptr(modem->mname[j]);
  1140. X            free_ptr(modem->init[j]);
  1141. X            free_ptr(modem->dial[j]);
  1142. X            free_ptr(modem->suffix[j]);
  1143. X            free_ptr(modem->hangup[j]);
  1144. X
  1145. X            free_ptr(modem->con_3[j]);
  1146. X            free_ptr(modem->con_12[j]);
  1147. X            free_ptr(modem->con_24[j]);
  1148. X            free_ptr(modem->con_48[j]);
  1149. X            free_ptr(modem->con_96[j]);
  1150. X            free_ptr(modem->con_192[j]);
  1151. X
  1152. X            free_ptr(modem->no_con1[j]);
  1153. X            free_ptr(modem->no_con2[j]);
  1154. X            free_ptr(modem->no_con3[j]);
  1155. X            free_ptr(modem->no_con4[j]);
  1156. X
  1157. X                    /* create an empty entry */
  1158. X            modem->mname[j] = null_ptr;
  1159. X            modem->init[j] = null_ptr;
  1160. X            modem->dial[j] = null_ptr;
  1161. X            modem->suffix[j] = null_ptr;
  1162. X            modem->hangup[j] = null_ptr;
  1163. X
  1164. X            modem->con_3[j] = null_ptr;
  1165. X            modem->con_12[j] = null_ptr;
  1166. X            modem->con_24[j] = null_ptr;
  1167. X            modem->con_48[j] = null_ptr;
  1168. X            modem->con_96[j] = null_ptr;
  1169. X            modem->con_192[j] = null_ptr;
  1170. X
  1171. X            modem->no_con1[j] = null_ptr;
  1172. X            modem->no_con2[j] = null_ptr;
  1173. X            modem->no_con3[j] = null_ptr;
  1174. X            modem->no_con4[j] = null_ptr;
  1175. X
  1176. X                    /* update the counts */
  1177. X            modem->m_entries--;
  1178. X            if (modem->m_cur >= modem->m_entries)
  1179. X                modem->m_cur = -1;
  1180. X            return;
  1181. X        }
  1182. X    }
  1183. X    return;
  1184. X}
  1185. SHAR_EOF
  1186. if test 9489 -ne "`wc -c < 'm_lib.c'`"
  1187. then
  1188.     echo shar: "error transmitting 'm_lib.c'" '(should have been 9489 characters)'
  1189. fi
  1190. fi
  1191. echo shar: "extracting 'main.c'" '(4860 characters)'
  1192. if test -f 'main.c'
  1193. then
  1194.     echo shar: "will not over-write existing file 'main.c'"
  1195. else
  1196. sed 's/^X//' << \SHAR_EOF > 'main.c'
  1197. X/*
  1198. X * Pcomm is a public domain telecommunication program for Unix
  1199. X * designed to operate similar to the popular MSDOS program, ProComm.
  1200. X * ProComm (TM) is copyrighted by Datastorm Technologies, Inc.
  1201. X *
  1202. X * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  1203. X * ...!ihnp4!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  1204. X *                    Directorate of Engineering & Housing
  1205. X *                    Environmental Management Office
  1206. X *                    Fort Hood, TX 76544-5057
  1207. X *    Beta release     7 Feb 88
  1208. X *    Release 1.0    12 Mar 88
  1209. X */
  1210. X
  1211. X#include <stdio.h>
  1212. X#include <signal.h>
  1213. X#include <curses.h>
  1214. X#ifndef OLDCURSES
  1215. X#include <term.h>
  1216. X#endif /* OLDCURSES */
  1217. X#include <sys/types.h>
  1218. X#include <sys/stat.h>
  1219. X#define MAIN
  1220. X#include "dial_dir.h"
  1221. X#include "modem.h"
  1222. X#include "param.h"
  1223. X#include "status.h"
  1224. X
  1225. X#ifdef OLDCURSES
  1226. Xchar bp[1024];
  1227. X#define cbreak crmode
  1228. X#endif /* OLDCURSES */
  1229. X
  1230. Xstruct PARAM *param;
  1231. Xstruct DIAL_DIR *dir;
  1232. Xstruct STATUS *status;
  1233. Xstruct MODEM *modem;
  1234. Xint xmc;
  1235. Xchar *null_ptr;
  1236. X
  1237. Xmain(argc, argv)
  1238. Xint argc;
  1239. Xchar *argv[];
  1240. X{
  1241. X    int c, ret_code, i, code, quit();
  1242. X    char *mytty, *ttyname(), *term, *getenv(), *index, *strdup();
  1243. X    char *extra_dir, buf[80], message[80];
  1244. X    struct PARAM *read_param();
  1245. X    struct DIAL_DIR *read_dir();
  1246. X    struct STATUS *init();
  1247. X    struct MODEM *read_modem();
  1248. X    struct stat stbuf;
  1249. X    void exit(), error_win(), input_on(), free_ptr();
  1250. X    extern char *optarg;
  1251. X#ifdef OLDCURSES
  1252. X    char *tgetstr(), ocbuf[20];
  1253. X    char *ocbufptr = ocbuf;
  1254. X#endif /* OLDCURSES */
  1255. X
  1256. X    signal(SIGINT, SIG_IGN);
  1257. X    signal(SIGQUIT, SIG_IGN);
  1258. X    signal(SIGTERM, quit);
  1259. X    signal(SIGHUP, quit);
  1260. X
  1261. X    null_ptr = "";
  1262. X    index = NULL;
  1263. X    extra_dir = NULL;
  1264. X                    /* the command line */
  1265. X    while ((c = getopt(argc, argv, "d:f:")) != EOF) {
  1266. X        switch (c) {
  1267. X            case 'd':    /* the extra directory to search */
  1268. X                extra_dir = strdup(optarg);
  1269. X                break;
  1270. X            case 'f':    /* the index into the dialing dir */
  1271. X                index = strdup(optarg);
  1272. X                break;
  1273. X            case '?':    /* default */
  1274. X                fprintf(stderr, "Usage: pcomm [-d directory] [-f index]\n");
  1275. X                exit(1);
  1276. X                break;
  1277. X        }
  1278. X    }
  1279. X                    /* get terminal type */
  1280. X    term = getenv("TERM");
  1281. X    if (term == NULL || *term == NULL) {
  1282. X        fprintf(stderr, "Windows not supported (TERM not defined)\n");
  1283. X        exit(1);
  1284. X    }
  1285. X                    /* see if terminfo entry exists */
  1286. X#ifdef OLDCURSES
  1287. X    ret_code = tgetent(bp, term);
  1288. X#else /* OLDCURSES */
  1289. X    setupterm(term, 1, &ret_code);
  1290. X#endif /* OLDCURSES */
  1291. X    if (ret_code != 1) {
  1292. X        fprintf(stderr, "Windows not supported (no terminfo data for '%s')\n", term);
  1293. X        exit(1);
  1294. X    }
  1295. X                    /* minimum screen size */
  1296. X#ifdef OLDCURSES
  1297. X    if (tgetnum("co") < 80 || tgetnum("li") < 24) {
  1298. X#else /* OLDCURSES */
  1299. X    if (columns < 80 || lines < 24) {
  1300. X#endif /* OLDCURSES */
  1301. X        fprintf(stderr, "Windows not supported (minimum 80x24 screen required)\n");
  1302. X        exit(1);
  1303. X    }
  1304. X                    /* must have cursor movement */
  1305. X#ifdef OLDCURSES
  1306. X    if (tgetstr("cm", &ocbufptr) == NULL) {
  1307. X#else /* OLDCURSES */
  1308. X    if (cursor_address == NULL) {
  1309. X#endif /* OLDCURSES */
  1310. X        fprintf(stderr, "Windows not supported (terminal too dumb)\n");
  1311. X        exit(1);
  1312. X    }
  1313. X                    /* load magic cookie variable */
  1314. X#ifdef OLDCURSES
  1315. X    xmc = tgetnum("sg");
  1316. X#else /* OLDCURSES */
  1317. X    xmc = magic_cookie_glitch;
  1318. X#endif /* OLDCURSES */
  1319. X                    /* ok... now lets go! */
  1320. X    initscr();
  1321. X    nonl();
  1322. X    cbreak();
  1323. X    noecho();
  1324. X
  1325. X    param = (struct PARAM *) NULL;
  1326. X    modem = (struct MODEM *) NULL;
  1327. X    dir = (struct DIAL_DIR *) NULL;
  1328. X                    /* show the herald, return status */
  1329. X    status = init(extra_dir, index);
  1330. X                    /* get 'msgs' status */
  1331. X    mytty = ttyname(0);
  1332. X    stat(mytty, &stbuf);
  1333. X    chmod(mytty, 0600);
  1334. X    status->msg = stbuf.st_mode & 0777;
  1335. X                    /* read the support files */
  1336. X    param = read_param();
  1337. X    dir = read_dir();
  1338. X    modem = read_modem();
  1339. X                    /* short-cut to dialing window ? */
  1340. X    code = 0;
  1341. X    if (index != NULL) {
  1342. X        for (i=1; i<dir->d_entries+1; i++) {
  1343. X            if (!strcmp(dir->index[i], index)) {
  1344. X                dir->q_num[0] = i;
  1345. X                dir->d_cur = i;
  1346. X                break;
  1347. X            }
  1348. X        }
  1349. X                    /* if match is found */
  1350. X        if (dir->q_num[0] != -1)
  1351. X            code = dial_win();
  1352. X        else {
  1353. X            sprintf(buf, "Can't find index '%s' in dialing directory file", index);
  1354. X            sprintf(message, "'%s'", status->d_path);
  1355. X            error_win(0, buf, message);
  1356. X        }
  1357. X        free_ptr(index);
  1358. X    }
  1359. X                    /* start terminal dialogue */
  1360. X    terminal(code);
  1361. X    exit(0);
  1362. X}
  1363. X
  1364. X/*
  1365. X * Something dreadful happened...  Cleanup the mess we made with the
  1366. X * tty driver and release the phone line.
  1367. X */
  1368. X
  1369. Xint
  1370. Xquit()
  1371. X{
  1372. X    void cleanup();
  1373. X
  1374. X    cleanup(1);
  1375. X                    /* never returns... */
  1376. X    return(0);
  1377. X}
  1378. X
  1379. X/*
  1380. X * Check write permission with the real UID and GID.  Returns a 0 on
  1381. X * permission denied, 1 on OK, and 2 on OK-but the file already exists.
  1382. X */
  1383. X
  1384. Xint
  1385. Xcan_write(file)
  1386. Xchar *file;
  1387. X{
  1388. X    char *p, path[200], *strcpy(), *strrchr();
  1389. X
  1390. X    p = strcpy(path, file);
  1391. X                    /* dissect the path component */
  1392. X    if (p = strrchr(path, '/'))
  1393. X        *(p++) = NULL;
  1394. X    else
  1395. X        strcpy(path, ".");
  1396. X                    /* if it already exists */
  1397. X    if (!access(file, 0)) {
  1398. X        if (!access(file, 2))
  1399. X            return(2);
  1400. X        return(0);
  1401. X    }
  1402. X                    /* if path is writable */
  1403. X    if (!access(path, 2))
  1404. X        return(1);
  1405. X    return(0);
  1406. X}
  1407. SHAR_EOF
  1408. if test 4860 -ne "`wc -c < 'main.c'`"
  1409. then
  1410.     echo shar: "error transmitting 'main.c'" '(should have been 4860 characters)'
  1411. fi
  1412. fi
  1413. echo shar: "extracting 'n_shell.c'" '(1369 characters)'
  1414. if test -f 'n_shell.c'
  1415. then
  1416.     echo shar: "will not over-write existing file 'n_shell.c'"
  1417. else
  1418. sed 's/^X//' << \SHAR_EOF > 'n_shell.c'
  1419. X/*
  1420. X * Spawn a 'native' shell.  'Native' means the shell found in the SHELL
  1421. X * environmental variable.
  1422. X */
  1423. X
  1424. X#include <stdio.h>
  1425. X#include <signal.h>
  1426. X#include <curses.h>
  1427. X
  1428. Xvoid
  1429. Xnative_shell()
  1430. X{
  1431. X    WINDOW *sh_win, *newwin();
  1432. X    int (*istat)(), (*qstat)(), status, pid, w;
  1433. X    char *shell, *shellpath, *getenv(), *strrchr();
  1434. X    unsigned int sleep();
  1435. X    void _exit();
  1436. X                    /* a full window */
  1437. X    sh_win = newwin(LINES, COLS, 0, 0);
  1438. X
  1439. X    clear_absolute(sh_win);
  1440. X    waddstr(sh_win, "Pcomm <=> Unix gateway, use ^D or 'exit' to return\n");
  1441. X    wrefresh(sh_win);
  1442. X                    /* out of curses mode */
  1443. X    resetterm();
  1444. X
  1445. X    shellpath = getenv("SHELL");
  1446. X    if (shellpath == NULL || *shellpath == NULL)
  1447. X        shellpath = "/bin/sh";
  1448. X
  1449. X    shell = strrchr(shellpath, '/') + 1;
  1450. X
  1451. X    if (!(pid = fork())) {
  1452. X#ifdef SGID
  1453. X        setgid(getgid());
  1454. X#endif /* SGID */
  1455. X        execl(shellpath, shell, "-i", 0);
  1456. X        _exit(1);
  1457. X    }
  1458. X    istat = signal(SIGINT, SIG_IGN);
  1459. X    qstat = signal(SIGQUIT, SIG_IGN);
  1460. X
  1461. X    while ((w = wait(&status)) != pid && w != -1)
  1462. X        ;
  1463. X
  1464. X    signal(SIGINT, istat);
  1465. X    signal(SIGQUIT, qstat);
  1466. X                    /* back to curses mode */
  1467. X    fixterm();
  1468. X    sleep(1);
  1469. X
  1470. X    clear_absolute(stdscr);
  1471. X    delwin(sh_win);
  1472. X    return;
  1473. X}
  1474. X
  1475. X/*
  1476. X * Clear the screen absolutely!  It's incrediblely hard to get curses() to
  1477. X * clear the screen when it thinks its already clear.
  1478. X */
  1479. X
  1480. Xint
  1481. Xclear_absolute(win)
  1482. XWINDOW *win;
  1483. X{
  1484. X    clearok(curscr, 1);
  1485. X    wrefresh(win);
  1486. X    clearok(curscr, 0);
  1487. X    return(0);
  1488. X}
  1489. SHAR_EOF
  1490. if test 1369 -ne "`wc -c < 'n_shell.c'`"
  1491. then
  1492.     echo shar: "error transmitting 'n_shell.c'" '(should have been 1369 characters)'
  1493. fi
  1494. fi
  1495. echo shar: "extracting 'p_lib.c'" '(5786 characters)'
  1496. if test -f 'p_lib.c'
  1497. then
  1498.     echo shar: "will not over-write existing file 'p_lib.c'"
  1499. else
  1500. sed 's/^X//' << \SHAR_EOF > 'p_lib.c'
  1501. X/*
  1502. X * Routines to manipulate the pcomm.param file.
  1503. X */
  1504. X
  1505. X#include <stdio.h>
  1506. X#include "param.h"
  1507. X#include "status.h"
  1508. X
  1509. X/*
  1510. X * Read the parameter structure from the pcomm.param file.  Returns a
  1511. X * pointer to the PARAM structure.  All errors are fatal.
  1512. X */
  1513. X
  1514. Xstruct PARAM *
  1515. Xread_param()
  1516. X{
  1517. X    FILE *fp;
  1518. X    int i, oops;
  1519. X    char buf[80], *temp_token, *str, *strdup();
  1520. X    char message[80], *str_tok();
  1521. X    static char *token[NUM_PARAM] = {"D_BAUD", "D_PARITY", "D_DBITS",
  1522. X    "D_SBITS", "HOT", "ASCII_HOT", "D_DUPLEX", "FLOW", "CR_IN", "CR_OUT",
  1523. X    "LOGFILE", "DUMPFILE", "STRIP", "PAUSE_CHAR", "CR_CHAR", "CTRL_CHAR",
  1524. X    "ESC_CHAR", "ABORT", "CDELAY", "PAUSE", "LECHO", "EXPAND", "CR_DELAY",
  1525. X    "PACE", "CR_UP", "LF_UP", "TIMER", "CR_DN", "LF_DN", "LD_PLUS",
  1526. X    "LD_MINUS", "LD_AT", "LD_POUND"};
  1527. X    static struct PARAM p;
  1528. X    void error_win();
  1529. X                    /* read permission already checked */
  1530. X    fp = fopen(status->p_path, "r");
  1531. X
  1532. X    oops = 0;
  1533. X    for (i=0; i<NUM_PARAM; i++) {
  1534. X        if (fgets(buf, 80, fp) == NULL) {
  1535. X            sprintf(message, "is truncated at line %d", i+1);
  1536. X            oops++;
  1537. X            break;
  1538. X        }
  1539. X                    /* parse the input line */
  1540. X        if (!(temp_token = str_tok(buf, '='))) {
  1541. X            sprintf(message, "is missing a token at line %d", i+1);
  1542. X            oops++;
  1543. X            break;
  1544. X        }
  1545. X        if (!(str = str_tok((char *) NULL, '\n'))) {
  1546. X            sprintf(message, "is missing a parameter at line %d", i+1);
  1547. X            oops++;
  1548. X            break;
  1549. X        }
  1550. X                    /* sanity checking */
  1551. X        if (strcmp(temp_token, token[i])) {
  1552. X            sprintf(message, "is corrupted at line %d", i+1);
  1553. X            oops++;
  1554. X            break;
  1555. X        }
  1556. X
  1557. X        switch(i) {
  1558. X                    /* used in line_set_menu() */
  1559. X            case LINE_SET:
  1560. X                p.d_baud = atoi(str);
  1561. X                break;
  1562. X            case LINE_SET+1:
  1563. X                p.d_parity = *str;
  1564. X                break;
  1565. X            case LINE_SET+2:
  1566. X                p.d_dbits = atoi(str);
  1567. X                break;
  1568. X            case LINE_SET+3:
  1569. X                p.d_sbits = atoi(str);
  1570. X                break;
  1571. X
  1572. X                    /* used in term_setup() */
  1573. X            case TERM_SETUP:
  1574. X                p.hot = atoi(str);
  1575. X                break;
  1576. X            case TERM_SETUP+1:
  1577. X                p.ascii_hot = strdup(str);
  1578. X                break;
  1579. X            case TERM_SETUP+2:
  1580. X                p.d_duplex = strdup(str);
  1581. X                break;
  1582. X            case TERM_SETUP+3:
  1583. X                p.flow = strdup(str);
  1584. X                break;
  1585. X            case TERM_SETUP+4:
  1586. X                p.cr_in = strdup(str);
  1587. X                break;
  1588. X            case TERM_SETUP+5:
  1589. X                p.cr_out = strdup(str);
  1590. X                break;
  1591. X
  1592. X                    /* used in gen_setup() */
  1593. X            case GEN_SETUP:
  1594. X                p.logfile = strdup(str);
  1595. X                break;
  1596. X            case GEN_SETUP+1:
  1597. X                p.dumpfile = strdup(str);
  1598. X                break;
  1599. X            case GEN_SETUP+2:
  1600. X                p.strip = strdup(str);
  1601. X                break;
  1602. X            case GEN_SETUP+3:
  1603. X                p.pause_char = *str;
  1604. X                break;
  1605. X            case GEN_SETUP+4:
  1606. X                p.cr_char = *str;
  1607. X                break;
  1608. X            case GEN_SETUP+5:
  1609. X                p.ctrl_char = *str;
  1610. X                break;
  1611. X            case GEN_SETUP+6:
  1612. X                p.esc_char = *str;
  1613. X                break;
  1614. X            case GEN_SETUP+7:
  1615. X                p.abort = strdup(str);
  1616. X                break;
  1617. X
  1618. X                    /* used in gen_setup() delay_times() */
  1619. X            case DELAY_TIMES:
  1620. X                p.cdelay = atoi(str);
  1621. X                break;
  1622. X            case DELAY_TIMES+1:
  1623. X                p.pause = atoi(str);
  1624. X                break;
  1625. X
  1626. X                    /* used in ascii_xfer_setup() */
  1627. X            case ASCII_SETUP:
  1628. X                p.lecho = strdup(str);
  1629. X                break;
  1630. X            case ASCII_SETUP+1:
  1631. X                p.expand = strdup(str);
  1632. X                break;
  1633. X            case ASCII_SETUP+2:
  1634. X                p.cr_delay = atoi(str);
  1635. X                break;
  1636. X            case ASCII_SETUP+3:
  1637. X                p.pace = strdup(str);
  1638. X                break;
  1639. X            case ASCII_SETUP+4:
  1640. X                p.cr_up = strdup(str);
  1641. X                break;
  1642. X            case ASCII_SETUP+5:
  1643. X                p.lf_up = strdup(str);
  1644. X                break;
  1645. X            case ASCII_SETUP+6:
  1646. X                p.timer = atoi(str);
  1647. X                break;
  1648. X            case ASCII_SETUP+7:
  1649. X                p.cr_dn = strdup(str);
  1650. X                break;
  1651. X            case ASCII_SETUP+8:
  1652. X                p.lf_dn = strdup(str);
  1653. X                break;
  1654. X
  1655. X                    /* used in d_revise() */
  1656. X            case LD_CODES:
  1657. X                p.ld_plus = strdup(str);
  1658. X                break;
  1659. X            case LD_CODES+1:
  1660. X                p.ld_minus = strdup(str);
  1661. X                break;
  1662. X            case LD_CODES+2:
  1663. X                p.ld_at = strdup(str);
  1664. X                break;
  1665. X            case LD_CODES+3:
  1666. X                p.ld_pound = strdup(str);
  1667. X                break;
  1668. X        }
  1669. X    }
  1670. X    fclose(fp);
  1671. X    if (oops) {
  1672. X        sprintf(buf, "Parameter file '%s'", status->p_path);
  1673. X        error_win(1, buf, message);
  1674. X    }
  1675. X    return(&p);
  1676. X}
  1677. X
  1678. X/*
  1679. X * Write the updated param structure to disk.  The values in memory should
  1680. X * have already been "purified".  Later, we'll update only the entries that
  1681. X * have been explicitly asked for.  A return code of 1 means non-fatal error.
  1682. X */
  1683. X
  1684. Xint
  1685. Xupdate_param()
  1686. X{
  1687. X    FILE *fp;
  1688. X    char buf[80];
  1689. X    void error_win();
  1690. X                    /* open for write */
  1691. X    if (!(fp = fopen(status->p_path, "w"))) {
  1692. X        sprintf(buf, "'%s'", status->p_path);
  1693. X        error_win(0, "No write permission on parameter file", buf);
  1694. X        return(1);
  1695. X    }
  1696. X
  1697. X    fprintf(fp, "D_BAUD=%d\n", param->d_baud);
  1698. X    fprintf(fp, "D_PARITY=%c\n", param->d_parity);
  1699. X    fprintf(fp, "D_DBITS=%d\n", param->d_dbits);
  1700. X    fprintf(fp, "D_SBITS=%d\n", param->d_sbits);
  1701. X    fprintf(fp, "HOT=%d\n", param->hot);
  1702. X    fprintf(fp, "ASCII_HOT=%s\n", param->ascii_hot);
  1703. X    fprintf(fp, "D_DUPLEX=%s\n", param->d_duplex);
  1704. X    fprintf(fp, "FLOW=%s\n", param->flow);
  1705. X    fprintf(fp, "CR_IN=%s\n", param->cr_in);
  1706. X    fprintf(fp, "CR_OUT=%s\n", param->cr_out);
  1707. X    fprintf(fp, "LOGFILE=%s\n", param->logfile);
  1708. X    fprintf(fp, "DUMPFILE=%s\n", param->dumpfile);
  1709. X    fprintf(fp, "STRIP=%s\n", param->strip);
  1710. X    fprintf(fp, "PAUSE_CHAR=%c\n", param->pause_char);
  1711. X    fprintf(fp, "CR_CHAR=%c\n", param->cr_char);
  1712. X    fprintf(fp, "CTRL_CHAR=%c\n", param->ctrl_char);
  1713. X    fprintf(fp, "ESC_CHAR=%c\n", param->esc_char);
  1714. X    fprintf(fp, "ABORT=%s\n", param->abort);
  1715. X    fprintf(fp, "CDELAY=%d\n", param->cdelay);
  1716. X    fprintf(fp, "PAUSE=%d\n", param->pause);
  1717. X    fprintf(fp, "LECHO=%s\n", param->lecho);
  1718. X    fprintf(fp, "EXPAND=%s\n", param->expand);
  1719. X    fprintf(fp, "CR_DELAY=%d\n", param->cr_delay);
  1720. X    fprintf(fp, "PACE=%s\n", param->pace);
  1721. X    fprintf(fp, "CR_UP=%s\n", param->cr_up);
  1722. X    fprintf(fp, "LF_UP=%s\n", param->lf_up);
  1723. X    fprintf(fp, "TIMER=%d\n", param->timer);
  1724. X    fprintf(fp, "CR_DN=%s\n", param->cr_dn);
  1725. X    fprintf(fp, "LF_DN=%s\n", param->lf_dn);
  1726. X    fprintf(fp, "LD_PLUS=%s\n", param->ld_plus);
  1727. X    fprintf(fp, "LD_MINUS=%s\n", param->ld_minus);
  1728. X    fprintf(fp, "LD_AT=%s\n", param->ld_at);
  1729. X    fprintf(fp, "LD_POUND=%s\n", param->ld_pound);
  1730. X
  1731. X    fclose(fp);
  1732. X    return(0);
  1733. X}
  1734. SHAR_EOF
  1735. if test 5786 -ne "`wc -c < 'p_lib.c'`"
  1736. then
  1737.     echo shar: "error transmitting 'p_lib.c'" '(should have been 5786 characters)'
  1738. fi
  1739. fi
  1740. echo shar: "extracting 'pexit.c'" '(2142 characters)'
  1741. if test -f 'pexit.c'
  1742. then
  1743.     echo shar: "will not over-write existing file 'pexit.c'"
  1744. else
  1745. sed 's/^X//' << \SHAR_EOF > 'pexit.c'
  1746. X/*
  1747. X * Exit pcomm.  A user requested abort.  There are a lot of things to do
  1748. X * before we exit!
  1749. X */
  1750. X
  1751. X#include <stdio.h>
  1752. X#include <curses.h>
  1753. X#include "dial_dir.h"
  1754. X#include "misc.h"
  1755. X#include "param.h"
  1756. X#include "status.h"
  1757. X
  1758. Xvoid
  1759. Xpexit(fd)
  1760. Xint fd;
  1761. X{
  1762. X    WINDOW *ex_win, *newwin();
  1763. X    void cleanup(), status_line();
  1764. X
  1765. X    ex_win = newwin(5, 33, 3, 7);
  1766. X
  1767. X    box(ex_win, '|', '-');
  1768. X    mvwattrstr(ex_win, 0, 3, A_BOLD, " Exit ");
  1769. X    if (yes_prompt(ex_win, 2, 4, A_BLINK, "Exit to Unix")) {
  1770. X        status_line("   exiting");
  1771. X        cleanup(0);
  1772. X    }
  1773. X    if (fd == -1) {
  1774. X        werase(ex_win);
  1775. X        wrefresh(ex_win);
  1776. X    }
  1777. X    delwin(ex_win);
  1778. X    return;
  1779. X}
  1780. X
  1781. X/*
  1782. X * Do the cleanup detail before we exit.
  1783. X */
  1784. X
  1785. Xvoid
  1786. Xcleanup(val)
  1787. Xint val;
  1788. X{
  1789. X    void release_port(), input_off(), exit(), status_line();
  1790. X    char *ttyname();
  1791. X                    /* kill the input routine */
  1792. X    input_off();
  1793. X                    /* zap the virtual screen file */
  1794. X    unlink(status->vs_path);
  1795. X                    /* release the port */
  1796. X    release_port(0);
  1797. X                    /* erase the window we made */
  1798. X    touchwin(stdscr);
  1799. X    clear();
  1800. X    refresh();
  1801. X    endwin();
  1802. X                    /* return the tty chmod */
  1803. X    chmod(ttyname(0), status->msg);
  1804. X    exit(val);
  1805. X}
  1806. X
  1807. X/*
  1808. X * Open a window to display an error message.  Handles both fatal and
  1809. X * non-fatal errors
  1810. X */
  1811. X
  1812. Xvoid
  1813. Xerror_win(code, line_one, line_two)
  1814. Xint code;
  1815. Xchar *line_one, *line_two;
  1816. X{
  1817. X    WINDOW *e_win, *newwin();
  1818. X    void cleanup(), status_line();
  1819. X
  1820. X    e_win = newwin(7, 70, 9, 5);
  1821. X                    /* display the nasty note */
  1822. X    mvwaddstr(e_win, 2, 4, line_one);
  1823. X    mvwaddstr(e_win, 3, 4, line_two);
  1824. X    box(e_win, '|', '-');
  1825. X
  1826. X    if (code) {
  1827. X        mvwattrstr(e_win, 0, 4, A_BOLD, " Error ");
  1828. X        mvwattrstr(e_win, 5, 24, A_BLINK, "Press any key to exit");
  1829. X        wmove(e_win, 5, 46);
  1830. X    }
  1831. X    else {
  1832. X        mvwattrstr(e_win, 0, 4, A_BOLD, " Warning ");
  1833. X        mvwattrstr(e_win, 5, 22, A_BLINK, "Press any key to continue");
  1834. X        wmove(e_win, 5, 48);
  1835. X    }
  1836. X    beep();
  1837. X    wrefresh(e_win);
  1838. X
  1839. X    wgetch(e_win);
  1840. X    werase(e_win);
  1841. X    wrefresh(e_win);
  1842. X    delwin(e_win);
  1843. X
  1844. X    if (code) {
  1845. X        /*
  1846. X         * Since this routine gets called if there is an error reading
  1847. X         * the support files, the dir and param structures can't be
  1848. X         * guaranteed to exist yet.
  1849. X         */
  1850. X        if (dir != NULL && param != NULL)
  1851. X            status_line("   exiting");
  1852. X        cleanup(code);
  1853. X    }
  1854. X    return;
  1855. X}
  1856. SHAR_EOF
  1857. if test 2142 -ne "`wc -c < 'pexit.c'`"
  1858. then
  1859.     echo shar: "error transmitting 'pexit.c'" '(should have been 2142 characters)'
  1860. fi
  1861. fi
  1862. echo shar: "extracting 'port.c'" '(6122 characters)'
  1863. if test -f 'port.c'
  1864. then
  1865.     echo shar: "will not over-write existing file 'port.c'"
  1866. else
  1867. sed 's/^X//' << \SHAR_EOF > 'port.c'
  1868. X/*
  1869. X * Routines to get or release a tty port.
  1870. X */
  1871. X
  1872. X#define LOCKDIR "/usr/spool/uucp"
  1873. X#undef ASCII_PID
  1874. X
  1875. X#include <stdio.h>
  1876. X#include <fcntl.h>
  1877. X#include <termio.h>
  1878. X#ifdef UNIXPC
  1879. X#include <sys/phone.h>
  1880. X#endif /* UNIXPC */
  1881. X#include "dial_dir.h"
  1882. X#include "modem.h"
  1883. X#include "status.h"
  1884. X
  1885. Xint getty_status;
  1886. X/*
  1887. X * Finds a free (or requested) serial port.  Creates a lock file to hold
  1888. X * it for our use.  Loads the modem database.  A return code of 1 means
  1889. X * all ports (or the requested port) are busy.
  1890. X */
  1891. X
  1892. Xint
  1893. Xget_port()
  1894. X{
  1895. X    int i, j, k, progpid, fd, list[NUM_TTY];
  1896. X    char file[80], buf[80], message[80], *strdup();
  1897. X    void error_win(), line_set(), release_port(), send_str();
  1898. X    void free_ptr();
  1899. X    
  1900. X    /*
  1901. X     * If we already have a port, see if it is good enough for the
  1902. X     * current request.
  1903. X     */
  1904. X    if (status->fd != -1) {
  1905. X        if (!strcmp(dir->index[dir->d_cur], modem->tty[modem->t_cur]) ||
  1906. X         modem->mbaud[modem->t_cur] >= dir->baud[dir->d_cur]) {
  1907. X            /*
  1908. X             * Re-initialize the modem because the baud
  1909. X             * rate (or other parameters) may have changed.
  1910. X             */
  1911. X            line_set();
  1912. X            send_str(modem->init[modem->m_cur]);
  1913. X            return(0);
  1914. X        }
  1915. X    }
  1916. X    release_port(1);
  1917. X
  1918. X    /*
  1919. X     * See if you want a specific tty port.  If the index field in the
  1920. X     * dialing directory is a valid device name, then use that tty.
  1921. X     */
  1922. X    sprintf(buf, "/dev/%s", dir->index[dir->d_cur]);
  1923. X    list[0] = -1;
  1924. X                    /* if index is a valid device */
  1925. X    if (!access(buf, 0)) {
  1926. X        for (i=0; i<modem->t_entries; i++) {
  1927. X                    /* and it exists in modem database */
  1928. X            if (!strcmp(dir->index[dir->d_cur], modem->tty[i])) {
  1929. X                list[0] = i;
  1930. X                list[1] = -1;
  1931. X                break;
  1932. X            }
  1933. X        }
  1934. X    }
  1935. X
  1936. X    /*
  1937. X     * Create a list of acceptable ttys.  It searches the tty database
  1938. X     * for the requested baud rate.
  1939. X     */
  1940. X    k = 0;
  1941. X    if (list[0] == -1) {
  1942. X        for (i=0; i<modem->t_entries; i++) {
  1943. X                    /* skip ports with no modems */
  1944. X            if (!strcmp(modem->tname[i], "DIRECT"))
  1945. X                continue;
  1946. X
  1947. X                    /* can handle requested baud rate ? */
  1948. X            if (modem->mbaud[i] >= dir->baud[dir->d_cur])
  1949. X                list[k++] = i;
  1950. X        }
  1951. X                    /* the end of list marker */
  1952. X        list[k] = -1;
  1953. X    }
  1954. X                    /* empty list ? */
  1955. X    if (list[0] == -1) {
  1956. X        sprintf(message, "No modem at a %d baud rating exists in", dir->baud[dir->d_cur]);
  1957. X        sprintf(file, "modem file '%s'", status->m_path);
  1958. X        error_win(0, message, file);
  1959. X        return(1);
  1960. X    }
  1961. X                    /* check the list for a free port */    
  1962. X    i = 0;
  1963. X    while (list[i] != -1) {
  1964. X                    /* create a lock file name */
  1965. X        sprintf(file, "%s/LCK..%s", LOCKDIR, modem->tty[list[i]]);
  1966. X
  1967. X        /*
  1968. X         * See if the lock file exists... We DO NOT look to see
  1969. X         * if the pid in the file is still active.  Maybe I'll
  1970. X         * change this later...
  1971. X         */
  1972. X        if (access(file, 0)) {
  1973. X            getty_status = set_getty(modem->tty[list[i]], 0);
  1974. X            
  1975. X            if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
  1976. X                set_getty(modem->tty[list[i]], 1);
  1977. X                sprintf(buf, "'%s'", file);
  1978. X                error_win(1, "Can't create the lockfile", buf);
  1979. X            }
  1980. X#ifdef ASCII_PID
  1981. X            sprintf(buf, "%10d\n", getpid());
  1982. X            write(fd, buf, 11);
  1983. X#else /* ASCII_PID */
  1984. X            progpid = getpid();
  1985. X            write(fd, (char *)&progpid, sizeof(int));
  1986. X#endif /* ASCII_PID */
  1987. X            close(fd);
  1988. X                    /* store the new values */
  1989. X            free_ptr(status->lock_path);
  1990. X            status->lock_path = strdup(file);
  1991. X            modem->t_cur = list[i];
  1992. X
  1993. X                    /* open the device (hold DTR high) */
  1994. X            sprintf(buf, "/dev/%s", modem->tty[list[i]]);
  1995. X            if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
  1996. X                set_getty(modem->tty[list[i]], 1);
  1997. X                sprintf(file, "Can't open port '%s' for read and write", buf);
  1998. X                error_win(1, file, NULL);
  1999. X            }
  2000. X
  2001. X                    /* turn off the "no delay" mode */
  2002. X            fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
  2003. X            status->fd = fd;
  2004. X                    /* change line settings */
  2005. X            line_set();
  2006. X                    /* load the modem data base */
  2007. X            for (j=0; j<modem->m_entries; j++) {
  2008. X                if (!strcmp(modem->tname[list[i]], modem->mname[j])) {
  2009. X                    modem->m_cur = j;
  2010. X                    break;
  2011. X                }
  2012. X            }
  2013. X                    /* initialize the modem */
  2014. X            send_str(modem->init[j]);
  2015. X            return(0);
  2016. X        }
  2017. X        i++;
  2018. X    }
  2019. X    error_win(0, "All ports are busy now, try again later", NULL);
  2020. X    return(1);
  2021. X}
  2022. X
  2023. X/*
  2024. X * Release the port.  Closes the file descriptor and removes the
  2025. X * lock file
  2026. X */
  2027. X
  2028. Xvoid
  2029. Xrelease_port(verbose)
  2030. Xint verbose;
  2031. X{
  2032. X    char buf[80];
  2033. X    extern char *null_ptr;
  2034. X    void free_ptr(), hang_up();
  2035. X
  2036. X    /*
  2037. X     * The modem structure can't be guaranteed to exist yet.  For example,
  2038. X     * an error in reading one of the other support files would cause
  2039. X     * this routine to be used before the MODEM structure gets allocated.
  2040. X     */
  2041. X    if (modem == NULL)
  2042. X        return;
  2043. X                    /* close the port */
  2044. X    if (status->fd != -1) {
  2045. X        ioctl(status->fd, TCFLSH, 2);
  2046. X        /*
  2047. X         * Since HUPCL is set, the close() should drop the DTR and
  2048. X         * hang up the modem (provided you've got the modem to
  2049. X         * respond to DTR).  Since this is not guaranteed, we send
  2050. X         * the hangup string first.
  2051. X         */
  2052. X        hang_up(verbose);
  2053. X        close(status->fd);
  2054. X    }
  2055. X                    /* remove the lock */
  2056. X    if (*status->lock_path != NULL) {
  2057. X        if (unlink(status->lock_path)) {
  2058. X            sprintf(buf, "'%s'", status->lock_path);
  2059. X            error_win(0, "Can't remove the lock file", buf);
  2060. X        }
  2061. X        free_ptr(status->lock_path);
  2062. X        status->lock_path = null_ptr;
  2063. X    }
  2064. X                    /* turn the getty back on? */
  2065. X    if (getty_status)
  2066. X        set_getty(modem->tty[modem->t_cur], 1);
  2067. X                    /* cleanup the structure */
  2068. X    status->fd = -1;
  2069. X    modem->m_cur = -1;
  2070. X    modem->t_cur = -1;
  2071. X    return;
  2072. X}
  2073. X
  2074. X/*
  2075. X * Turn the /etc/getty on or off for the specified port.  A return code
  2076. X * of 1 means that the getty was on.  Systems with uugetty or dedicated
  2077. X * dialout ports won't need this routine.
  2078. X */
  2079. X
  2080. Xint
  2081. Xset_getty(tty, on)
  2082. Xchar *tty;
  2083. Xint on;
  2084. X{
  2085. X#ifdef UNIXPC
  2086. X    int i, ret_code;
  2087. X    char buf[40];
  2088. X    unsigned int sleep();
  2089. X                    /* the last three characters */
  2090. X    i = strlen(tty) -3;
  2091. X
  2092. X    ret_code = 0;
  2093. X    if (on) {
  2094. X        sprintf(buf, "setgetty %s 1", tty+i);
  2095. X        system(buf);
  2096. X    }
  2097. X    else {
  2098. X        sprintf(buf, "setgetty %s 0", tty+i);
  2099. X        if (system(buf) == 512)
  2100. X            ret_code = 1;
  2101. X        sleep(1);
  2102. X    }
  2103. X    return(ret_code);
  2104. X#else /* UNIXPC */
  2105. X    /*
  2106. X     * If you don't have one of these cute little routines, you
  2107. X     * might wanna write one.  It should check for an existing lock
  2108. X     * file, edit the /etc/inittab file, and issue an init -q.
  2109. X     * Obviously the program would be suid to root.
  2110. X     */
  2111. X    return(0);
  2112. X#endif /* UNIXPC */
  2113. X}
  2114. SHAR_EOF
  2115. if test 6122 -ne "`wc -c < 'port.c'`"
  2116. then
  2117.     echo shar: "error transmitting 'port.c'" '(should have been 6122 characters)'
  2118. fi
  2119. fi
  2120. echo shar: "extracting 'redial.c'" '(2216 characters)'
  2121. if test -f 'redial.c'
  2122. then
  2123.     echo shar: "will not over-write existing file 'redial.c'"
  2124. else
  2125. sed 's/^X//' << \SHAR_EOF > 'redial.c'
  2126. X/*
  2127. X * The redial option (actually a misnomer, it's really a queuing system).
  2128. X * We expect a space-separated list of dialing directory entries (although
  2129. X * new users always try to put in a phone number).  A return code of 1
  2130. X * means we're ready to dial.
  2131. X */
  2132. X
  2133. X#include <stdio.h>
  2134. X#include <curses.h>
  2135. X#include "dial_dir.h"
  2136. X#include "misc.h"
  2137. X
  2138. Xint
  2139. Xredial(fd)
  2140. Xint fd;
  2141. X{
  2142. X    WINDOW *rd_win, *newwin();
  2143. X    char *ans, *entry, *get_str(), *strchr(), *strtok();
  2144. X    int i, oops, number, ret_code;
  2145. X    
  2146. X    rd_win = newwin(6, 70, 5, 5);
  2147. X
  2148. X    mvwaddstr(rd_win, 4, 23, "(CR for previous numbers)");
  2149. X    mvwaddstr(rd_win, 2, 4, "Directory Entry Number(s): ");
  2150. X    box(rd_win, '|', '-');
  2151. X
  2152. X    mvwattrstr(rd_win, 0, 3, A_BOLD, " Redial Queue ");
  2153. X    wmove(rd_win, 2, 31);
  2154. X    wrefresh(rd_win);
  2155. X                    /* get the string of numbers */
  2156. X    ret_code = 0;
  2157. X    while ((ans = get_str(rd_win, 35, "0123456789+-@# ", NULL)) != NULL) {
  2158. X        oops = 0;
  2159. X        if (*ans == NULL) {
  2160. X                    /* use previous queue */
  2161. X            if (dir->q_num[0] != -1) {
  2162. X                ret_code = 1;
  2163. X                break;
  2164. X            }
  2165. X                    /* there is no previous queue */
  2166. X            beep();
  2167. X            mvwattrstr(rd_win, 3, 4, A_BOLD, "No previous numbers");
  2168. X            wrefresh(rd_win);
  2169. X            wait_key(rd_win, 3);
  2170. X            clear_line(rd_win, 3, 4, 1);
  2171. X            wmove(rd_win, 2, 31);
  2172. X            wrefresh(rd_win);
  2173. X            continue;
  2174. X        }
  2175. X                    /* parse the queue values */
  2176. X        entry = strtok(ans, "     ");
  2177. X        for (i=0; i<NUM_QUEUE; i++) {
  2178. X            if (*entry == NULL) {
  2179. X                dir->q_num[i] = -1;
  2180. X                continue;
  2181. X            }
  2182. X                    /* is there a LD code ? */
  2183. X            dir->q_ld[i] = NULL;
  2184. X            if (strchr("+-@#", *entry)) {
  2185. X                dir->q_ld[i] = *entry;
  2186. X                entry++;
  2187. X            }
  2188. X
  2189. X            /*
  2190. X             * Zero is valid here, because it means use
  2191. X             * the current entry information.
  2192. X             */
  2193. X            number = atoi(entry);
  2194. X            if (number < -1 || number > NUM_DIR) {
  2195. X                beep();
  2196. X                mvwattrstr(rd_win, 3, 4, A_BOLD, "Invalid directory entry number");
  2197. X                wrefresh(rd_win);
  2198. X                wait_key(rd_win, 3);
  2199. X                clear_line(rd_win, 3, 4, 1);
  2200. X                clear_line(rd_win, 2, 31, 1);
  2201. X                wrefresh(rd_win);
  2202. X                oops++;
  2203. X                break;
  2204. X            }
  2205. X                    /* store the number in the queue */
  2206. X            dir->q_num[i] = number;
  2207. X            entry = strtok((char *) NULL, "     ");
  2208. X        }
  2209. X        if (oops)
  2210. X            continue;
  2211. X        ret_code = 1;
  2212. X        break;
  2213. X    }
  2214. X    if (fd == -1) {
  2215. X        werase(rd_win);
  2216. X        wrefresh(rd_win);
  2217. X    }
  2218. X    delwin(rd_win);
  2219. X    return(ret_code);
  2220. X}
  2221. SHAR_EOF
  2222. if test 2216 -ne "`wc -c < 'redial.c'`"
  2223. then
  2224.     echo shar: "error transmitting 'redial.c'" '(should have been 2216 characters)'
  2225. fi
  2226. fi
  2227. exit 0
  2228. #    End of shell archive
  2229.  
  2230.  
  2231.